<template>
  <div style="width: 100%;">
    <div ref="myChart" id="my-chart"></div>
  </div>
</template>

<script setup name="GradientBar">
import * as echarts from 'echarts';
import { onMounted, ref, toRefs } from 'vue';

const Props = defineProps({
  totalData: {
    type: Array,
    default: () => [220, 182, 191, 234, 290],
  },
  overData: {
    type: Array,
    default: () => [120, 132, 101, 134, 90],
  },
  xAxisData: {
    type: Array,
    default: () => ["数据1","数据2","数据3","数据4","数据5"],
  },
});

const { totalData, overData, xAxisData } = toRefs(Props);

const myChart = ref(null);
const isAll = ref(true);
const isFinish = ref(true);
const option = ref(null);
let charts = ref(null)

const drawLine = () => {
  // 基于准备好的dom，初始化echarts实例
  charts.on('legendselectchanged', (obj) => {
    if (!obj) {
      isFinish.value = true;
      isAll.value = true;
    } else {
      isFinish.value = obj.selected['完成数量'];
      isAll.value = obj.selected['目标数量'];
    }
    setChart();
  });
};

const initOption = () => {
  option.value = {
    color: ['#1890FF', '#1EE7E7'],
    tooltip: {
      show: true,
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      formatter: function (params) {
        var total = params.find((x) => x.seriesName == '目标数量').data;
        var finish = params.find((x) => x.seriesName == '完成数量').data;
        var res = `
             <p>${params[0].axisValueLabel}</p>
             <span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#1EE7E7;\"></span><span>目标数量:${total}</span></br>
             <span style=\"display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:#1890FF;\"></span><span>完成数量:${finish}</span>
             `;
        return res;
      },
    },
    legend: {
      data: ['完成数量', '目标数量'],
      top: 10,
      selected: {
        完成数量: isFinish.value,
        目标数量: isAll.value,
      },
      textStyle: {
        color: '#FFF',
      },
    },
    grid: {
      left: '2%',
      right: '2%',
      bottom: '10%',
      containLabel: true,
    },
    xAxis: [
      {
        type: 'category',
        data: xAxisData.value, // x轴所要展示的数据
        axisLine: {
          // 坐标轴轴线的相关设置
          lineStyle: {
            // 线的样式
            color: 'rgba(255,255,255,0.70)', // 坐标轴线线的颜色
          },
          show: true, // 是否显示坐标轴轴线
        },
        axisTick: {
          // 坐标轴刻度的相关设置
          alignWithLabel: true, // 刻度线和标签对齐
        },
        axisLabel: {
          margin: 15,
        },
      },
    ],
    yAxis: [
      {
        type: 'value',
        show: true, // 是否显示y轴
        splitLine: {
          lineStyle: {
            show: true,
            color: 'rgba(255,255,255,0.5)',
            type: 'dashed',
            width: 0.8,
          },
        },
        axisLabel: {
          //y轴文字的配置
          textStyle: {
            color: 'rgba(255,255,255,0.70)',
            margin: 15,
          },
        },
        axisLine: {
          show: false,
        },
      },
    ],
    series: [
      {
        // 下右
        type: 'custom',
        stack: 'right',
        name: '完成数量',
        renderItem: (params, api) => {
          const location = api.coord([api.value(0), api.value(1)]);
          return {
            type: 'InclinedRoofRight',
            shape: {
              api,
              xValue: api.value(0),
              yValue: api.value(1),
              x: location[0],
              y: location[1],
              xAxisPoint: api.coord([api.value(0), 0]),
            },
            style: {
              fill: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  //代表渐变色从正上方开始
                  offset: 0, //offset范围是0~1，用于表示位置，0是指0%处的颜色
                  color: 'rgba(24,144,255,0.35)',
                }, //柱图渐变色
                {
                  offset: 1, //指100%处的颜色
                  color: '#1890FF',
                },
              ]),
            },
          };
        },
        data: [],
        z: 2,
      },
      {
        // 下左
        type: 'custom',
        stack: 'left',
        name: '完成数量',
        renderItem: (params, api) => {
          const location = api.coord([api.value(0), api.value(1)]);
          return {
            type: 'InclinedRoofLeft',
            shape: {
              api,
              xValue: api.value(0),
              yValue: api.value(1),
              x: location[0],
              y: location[1],
              xAxisPoint: api.coord([api.value(0), 0]),
            },
            style: {
              fill: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  //代表渐变色从正上方开始
                  offset: 0, //offset范围是0~1，用于表示位置，0是指0%处的颜色
                  color: 'rgba(16,112,201,0.35)',
                }, //柱图渐变色
                {
                  offset: 1, //指100%处的颜色
                  color: '#1070C9',
                },
              ]),
            },
          };
        },
        data: [],
        z: 2,
      },
      {
        // 上左
        type: 'custom',
        stack: 'left',
        name: '目标数量',
        renderItem: (params, api) => {
          const location = api.coord([api.value(0), api.value(1)]);
          return {
            type: 'InclinedRoofLeft',
            shape: {
              api,
              xValue: api.value(0),
              yValue: api.value(1),
              x: location[0],
              y: location[1],
              xAxisPoint: api.coord([api.value(0), 0]),
            },
            style: {
              fill: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  //代表渐变色从正上方开始
                  offset: 0, //offset范围是0~1，用于表示位置，0是指0%处的颜色
                  color: 'rgba(19,173,173,0.35)',
                }, //柱图渐变色
                {
                  offset: 1, //指100%处的颜色
                  color: '#13ADAD',
                },
              ]),
            },
          };
        },
        data: [],
        z: 1,
      },
      {
        // 上右
        type: 'custom',
        stack: 'right',
        name: '目标数量',
        renderItem: (params, api) => {
          const location = api.coord([api.value(0), api.value(1)]);
          return {
            type: 'InclinedRoofRight',
            shape: {
              api,
              xValue: api.value(0),
              yValue: api.value(1),
              x: location[0],
              y: location[1],
              xAxisPoint: api.coord([api.value(0), 0]),
            },
            style: {
              fill: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
                {
                  //代表渐变色从正上方开始
                  offset: 0, //offset范围是0~1，用于表示位置，0是指0%处的颜色
                  color: 'rgba(30,231,231,0.35) ',
                }, //柱图渐变色
                {
                  offset: 1, //指100%处的颜色
                  color: '#1EE7E7',
                },
              ]),
            },
          };
        },
        data: [],
        z: 1,
      },
      {
        // 头部
        type: 'pictorialBar',
        name: '目标数量Top',
        z: 10,
        animation: false,
        data: [],
      },
    ],
  };
}

const setChart = () => {
  option.value.legend.selected = {
    完成数量: isFinish.value,
    目标数量: isAll.value,
  }
  if (isAll.value && isFinish.value) {
    setOption();
  } else if (isAll.value && !isFinish.value) {
    setOption1();
  } else if (!isAll.value && isFinish.value) {
    setOption2();
  } else {
    setOption3();
  }
};

// isAll:true isFinish:true
const setOption = () => {
  option.value.series[0].data = overData;
  option.value.series[1].data = overData;
  option.value.series[2].data = totalData.value;
  option.value.series[3].data = totalData.value;
  option.value.series[4].data = totalData.value.map( J => {
    return {
      value: J,
      symbol: 'diamond',
      symbolOffset: [0, '-50%'],
      symbolPosition: 'end',//图形边缘与柱子结束的地方内切
      symbolSize: [40, 30],//根据柱子大小来做调整
      itemStyle: {
        normal: {
          color: '#1EE7E7'
        }
      }
    }
  });
  charts.setOption(option.value);
};

// isAll:true isFinish:false
const setOption1 = () => {
  option.value.series[0].data = overData.value.map((J) => 0);
  option.value.series[1].data = overData.value.map((J) => 0);
  option.value.series[2].data = totalData.value;
  option.value.series[3].data = totalData.value;
  option.value.series[4].data = totalData.value.map( J => {
    return {
      value: J,
      symbol: 'diamond',
      symbolOffset: [0, '-50%'],
      symbolPosition: 'end',//图形边缘与柱子结束的地方内切
      symbolSize: [40, 30],//根据柱子大小来做调整
      itemStyle: {
        normal: {
          color: '#1EE7E7'
        }
      }
    }
  });
  charts.setOption(option.value);
};

// isAll:false isFinish:true
const setOption2 = () => {
  option.value.series[0].data = overData.value;
  option.value.series[1].data = overData.value;
  option.value.series[2].data = totalData.value.map((J) => 0);
  option.value.series[3].data = totalData.value.map((J) => 0);
  option.value.series[4].data = overData.value.map((J) => {
    return {
      value: J,
      symbol: 'diamond',
      symbolOffset: [0, '-50%'],
      symbolPosition: 'end', //图形边缘与柱子结束的地方内切
      symbolSize: [40, 30], //根据柱子大小来做调整
      itemStyle: {
        normal: {
          color: '#1070C9',
        },
      },
    };
  });
  charts.setOption(option.value);
};
// isAll:false isFinish:false
const setOption3 = () => {
  option.value.series[0].data = overData.value.map((J) => 0);
  option.value.series[1].data = overData.value.map((J) => 0);
  option.value.series[2].data = totalData.value.map((J) => 0);
  option.value.series[3].data = totalData.value.map((J) => 0);
  option.value.series[4].data = totalData.value.map((J) => {
    return {
      value: null,
      symbol: 'diamond',
      symbolOffset: [0, '-1-0%'],
      symbolPosition: 'end', //图形边缘与柱子结束的地方内切
      symbolSize: ['-65%', 30], //根据柱子大小来做调整
      itemStyle: {
        normal: {
          color: '#1EE7E7',
        },
      },
    };
  });
  charts.setOption(option.value);
};
const initChart = () => {
  charts = echarts.init(myChart.value);
  initOption();
  const myShape = {
    x: 0,
    y: 0,
    width: 20, //柱宽
  };
  // 绘制右侧面
  const InclinedRoofRight = echarts.graphic.extendShape({
    shape: myShape,
    buildPath: function (ctx, shape) {
      const xAxisPoint = shape.xAxisPoint;
      const c0 = [shape.x, shape.y + 15];
      const c1 = [shape.x + 20, shape.y];
      const c2 = [xAxisPoint[0] + 20, xAxisPoint[1]];
      const c3 = [xAxisPoint[0], xAxisPoint[1] + 15];
      ctx
        .moveTo(c0[0], c0[1])
        .lineTo(c1[0], c1[1])
        .lineTo(c2[0], c2[1])
        .lineTo(c3[0], c3[1])
        .closePath();
    },
  });
  // 注册三个面图形
  echarts.graphic.registerShape('InclinedRoofRight', InclinedRoofRight);
  // 绘制左侧面
  const InclinedRoofLeft = echarts.graphic.extendShape({
    shape: myShape,
    buildPath: function (ctx, shape) {
      const xAxisPoint = shape.xAxisPoint;
      const c0 = [shape.x, shape.y + 15];
      const c1 = [shape.x - 20, shape.y];
      const c2 = [xAxisPoint[0] - 20, xAxisPoint[1]];
      const c3 = [xAxisPoint[0], xAxisPoint[1] + 15];
      ctx
        .moveTo(c0[0], c0[1])
        .lineTo(c1[0], c1[1])
        .lineTo(c2[0], c2[1])
        .lineTo(c3[0], c3[1])
        .closePath();
    },
  });
  // 注册三个面图形
  echarts.graphic.registerShape('InclinedRoofLeft', InclinedRoofLeft);
  charts = echarts.init(myChart.value);
  setChart();
  drawLine();
}
onMounted(() => {
  initChart();
  myChart.value.children[0].style.width = '100%';
  myChart.value.children[0].children[0].style.width = '100%';
  setTimeout(() => {
    charts.resize();
  }, 100);
});
</script>

<style lang="scss" scoped>
#my-chart {
  width: 100%;
  height: 300px;
  background: #182d6cc9;
  & > div {
    width: 100%;
    & > :first-child {
      width: 100%;
    }
  }
}
</style>